Skip to content

Port ComplexWatsonDistribution from libDirectional MATLAB to Python#1650

Open
Copilot wants to merge 3 commits intomainfrom
copilot/port-complex-watson-distribution
Open

Port ComplexWatsonDistribution from libDirectional MATLAB to Python#1650
Copilot wants to merge 3 commits intomainfrom
copilot/port-complex-watson-distribution

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 6, 2026

Summary

Ports the ComplexWatsonDistribution from MATLAB/libDirectional to Python.

Reference

Mardia, K. V. & Dryden, I. L., The Complex Watson Distribution and Shape Analysis, JRSS-B, 1999, 61, 913–926.

Changes

New file: pyrecest/distributions/hypersphere_subset/complex_watson_distribution.py

Implements ComplexWatsonDistribution – a distribution over the complex unit sphere C^D with pdf:

f(z) = C_D(κ) · exp(κ · |μᴴ z|²)

Methods:

  • __init__(mu, kappa) – takes complex unit vector mu (shape (D,)) and scalar kappa
  • mean() – returns mu
  • pdf(za) – evaluates density at rows of complex array za (shape (N, D))
  • sample(n) – samples n points on the complex unit sphere using the complex Bingham sampling algorithm (Mardia & Jupp 2009, p. 336)
  • log_norm(D, kappa) – static; log normalization constant using three numerical regimes (low/medium/high κ) for stability across the full κ range
  • fit(Z, weights=None) – classmethod; MLE fit
  • estimate_parameters(Z, weights=None) – static; Mardia & Dryden MLE (scatter matrix eigendecomposition + hypergeometric ratio inversion)
  • _hypergeometric_ratio_inverse(rho, D, kappa_max) – static; solves 1F1(2;D+1;κ) / (D · 1F1(1;D;κ)) = ρ using mpmath + scipy.optimize.brentq

Updated: pyrecets/distributions/__init__.py

  • Imports and exports ComplexWatsonDistribution

New file: pyrecest/tests/distributions/test_complex_watson_distribution.py

20 unit tests covering: construction, mean(), log_norm(), pdf() (symmetry/phase-invariance/positivity), sample() (shape/unit-norm), and estimate_parameters()/fit().

Notes

  • Uses numpy directly for complex arithmetic (no pyrecets backend abstraction needed since complex tensor support varies across backends)
  • mpmath is used for the hypergeometric function evaluations to avoid float64 overflow for large κ

Copilot AI and others added 2 commits April 6, 2026 06:06
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 6, 2026

MegaLinter analysis: Success

Descriptor Linter Files Fixed Errors Warnings Elapsed time
✅ COPYPASTE jscpd yes no no 8.76s
✅ JSON prettier 2 0 0 0 0.66s
✅ JSON v8r 2 0 0 2.67s
✅ MARKDOWN markdownlint 1 0 0 0 0.65s
✅ MARKDOWN markdown-table-formatter 1 0 0 0 0.22s
✅ PYTHON bandit 288 0 0 3.65s
✅ PYTHON black 288 8 0 0 5.63s
✅ PYTHON flake8 288 0 0 2.09s
✅ PYTHON isort 288 12 0 0 0.56s
✅ PYTHON mypy 288 0 0 4.19s
✅ PYTHON pylint 288 0 0 83.37s
✅ PYTHON ruff 288 12 0 0 0.05s
✅ REPOSITORY checkov yes no no 22.39s
✅ REPOSITORY gitleaks yes no no 4.99s
✅ REPOSITORY git_diff yes no no 0.02s
✅ REPOSITORY secretlint yes no no 6.21s
✅ REPOSITORY syft yes no no 3.96s
✅ REPOSITORY trivy-sbom yes no no 1.66s
✅ REPOSITORY trufflehog yes no no 18.27s
✅ YAML prettier 4 0 0 0 0.5s
✅ YAML v8r 4 0 0 5.67s
✅ YAML yamllint 4 0 0 0.45s

See detailed reports in MegaLinter artifacts

Your project could benefit from a custom flavor, which would allow you to run only the linters you need, and thus improve runtime performances. (Skip this info by defining FLAVOR_SUGGESTIONS: false)

  • Documentation: Custom Flavors
  • Command: npx mega-linter-runner@9.4.0 --custom-flavor-setup --custom-flavor-linters PYTHON_PYLINT,PYTHON_BLACK,PYTHON_FLAKE8,PYTHON_ISORT,PYTHON_BANDIT,PYTHON_MYPY,PYTHON_RUFF,COPYPASTE_JSCPD,JSON_V8R,JSON_PRETTIER,MARKDOWN_MARKDOWNLINT,MARKDOWN_MARKDOWN_TABLE_FORMATTER,REPOSITORY_CHECKOV,REPOSITORY_GIT_DIFF,REPOSITORY_GITLEAKS,REPOSITORY_SECRETLINT,REPOSITORY_SYFT,REPOSITORY_TRIVY_SBOM,REPOSITORY_TRUFFLEHOG,YAML_PRETTIER,YAML_YAMLLINT,YAML_V8R

MegaLinter is graciously provided by OX Security
Show us your support by starring ⭐ the repository

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 6, 2026

Test Results

0 tests   0 ✅  0s ⏱️
0 suites  0 💤
0 files    0 ❌

Results for commit 653013a.

♻️ This comment has been updated with latest results.

@FlorianPfaff FlorianPfaff marked this pull request as ready for review April 14, 2026 13:39
@FlorianPfaff
Copy link
Copy Markdown
Owner

@copilot Suppress the the linter warnings:

************* Module pyrecest.distributions.hypersphere_subset.complex_watson_distribution
pyrecest/distributions/hypersphere_subset/complex_watson_distribution.py:64:4: R0914: Too many local variables (16/15) (too-many-locals)
pyrecest/distributions/hypersphere_subset/complex_watson_distribution.py:230:4: R0914: Too many local variables (17/15) (too-many-locals)


Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 14, 2026

@copilot Suppress the the linter warnings:

************* Module pyrecest.distributions.hypersphere_subset.complex_watson_distribution
...

Added # pylint: disable=too-many-locals to the closing """ line of both sample() and log_norm() in commit 653013a.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants